#include "CNetwork.h"

CNetwork::CNetwork()
{
    server = new QTcpServer;

    c_database = new CDataBase;
}

CNetwork::~CNetwork()
{
    delete server;
}

QTcpServer* CNetwork::get_server()
{
    return this->server;
}

QMap <QTcpSocket*, MClient*> CNetwork::get_clients()
{
    return this->clients;
}

// Ne pas toucher
QTcpSocket* CNetwork::wait_connection()
{
    QTcpSocket* client = server->nextPendingConnection();

    QObject::connect(client, SIGNAL(readyRead()), this, SLOT(select_action()));
    QObject::connect(client, SIGNAL(disconnected()), this, SLOT(disco()));

    MClient* m_client = new MClient(client);

    clients[client] = m_client;

    return client;
}

// Ne pas toucher
bool CNetwork::start_listen(quint16 port)
{
    server->listen(QHostAddress::Any, port);

    QObject::connect(server, SIGNAL(newConnection()), this, SLOT(wait_connection()));

    return server->isListening();
}

// Ne pas toucher
void CNetwork::send(QTcpSocket* socket, QString message)
{
    // Paquet final
    QByteArray paquet;
    // Flux de sortie
    QDataStream out(&paquet, QIODevice::WriteOnly);

    out << (quint16) 0;
    out << message;
    out.device()->seek(0);
    out << (quint16) (paquet.size() - sizeof(quint16));

    socket->write(paquet);
}


// Ne pas toucher
QString CNetwork::receive(QTcpSocket *destinataire)
{
    // Envoie un signal pour indiquer qu'un message arrive
    emit is_receiving();

    // S'il y a quelque chose a lire
    if(destinataire->bytesAvailable() > 0)
    {
        // On assigne la taille du message a 0
        quint16 taille_message = 0;
        // Si la source est valide
        if(destinataire!=0)
        {
            // On lit la source
            QDataStream in(destinataire);
            // On recupere la taille totale du message
            while(destinataire->bytesAvailable() < sizeof(quint16)) {}
            in >> taille_message;

            // On recupere le message
            while(destinataire->bytesAvailable() < taille_message) {}

            // On rettourne le message sous forme de QString
            QString message;
            in >> message;
            return message;
        }
    }
    // S'il n'y a rien a lire
    else
    {
        return "";
    }
    // En cas d'erreur
    return "";
}

// Toucher !
void CNetwork::select_action()
{
    QTcpSocket *destinataire = qobject_cast<QTcpSocket *>(sender());
    QString action = this->receive(destinataire);
    if(action == "login")
    {
        emit login(clients[destinataire]);
    }
    else if(action == "chat")
    {
        emit receive_chat(destinataire);
    }
    else if(action == "new_chat")
    {
        emit new_chat_client(destinataire);
    }
}

// Toucher !
void CNetwork::disco()
{
    QTcpSocket *destinataire = qobject_cast<QTcpSocket *>(sender());
    emit discoo(destinataire);
}
